<?php

namespace App\Services;

use App\Models\NodeManagement;
use App\Models\SwitchPort;
use App\Models\SwitchPortFlow;
use Slowlyo\OwlAdmin\Services\AdminService;
use App\Services\IdcnodeService;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

/**
 * 节点管理
 *
 * @method NodeManagement getModel()
 * @method NodeManagement|\Illuminate\Database\Query\Builder query()
 */
class NodeManagementService extends AdminService
{
	protected string $modelName = NodeManagement::class;

	public function searchable($query)
	{
		parent::searchable($query);

		$query->when($this->request->input('type_id'), function($q, $typeId) {
			$q->where('type_id', $typeId);
		});

		$query->when($this->request->input('idc_id'), function($q, $idcId) {
			$q->where('idc_id', $idcId);
		});
	}

	public function listQuery()
	{
		$query = parent::listQuery()->with([
			'operator:id,name',
			'switch:id,name,status',
			'customer_bus'
		]);

		return $query;
	}

	/**
	 * 重写父类的 formatRows 方法来处理流量统计
	 */
	public function formatRows(array $rows)
	{
		foreach ($rows as $node) {
			$usageStats = $this->calculateNodeUsageStats($node);
			
			// 添加计算结果到节点数据中
			$node->yiyong = $usageStats['used_points'];
			$node->yiyong_minutes = $usageStats['used_minutes'];
			$node->shengyu = $usageStats['remaining_points'];
			$node->shengyu_minutes = $usageStats['remaining_minutes'];
		}

		return $rows;
	}

	/**
	 * 计算节点的使用统计
	 */
	protected function calculateNodeUsageStats($node)
	{
		// 获取端口列表
		$portIds = explode(',', $node->port_list);
        
		// 获取当前月份的天数
		$daysInMonth = Carbon::now()->daysInMonth;

        
		
		// 获取端口信息
		$ports = SwitchPort::whereIn('id', $portIds)
			->select('id', 'switch_id', 'port_index')
			->get();
            
      

		// 计算本月已用点位
		$usedPoints = $this->calculateUsedPoints($ports, $node->reference_95_value);
		
		// 计算已用分钟
		$usedMinutes = $usedPoints * 5;
		
		// 计算总点位数
		$totalPoints = $daysInMonth * 288;
		
		// 计算安全点位 (5%)
		$safePoints = $totalPoints * 0.05;

		// 计算剩余点位
		$remainingPoints = $safePoints - $usedPoints;
		
		// 计算剩余分钟
		$remainingMinutes = $remainingPoints * 5;

		return [
			'used_points' => (int)$usedPoints,
			'used_minutes' => (int)$usedMinutes,
			'remaining_points' => (int)$remainingPoints,
			'remaining_minutes' => (int)$remainingMinutes,
		];
	}

	/**
	 * 计算已用点位
	 */
	protected function calculateUsedPoints($ports, $referenceValue)
	{
		$usedPoints = 0;
		
		// 获取当月开始和结束时间
		$startOfMonth = (string)Carbon::now()->startOfMonth()->getTimestamp();
		$endOfMonth = (string)Carbon::now()->endOfMonth()->getTimestamp();

		// 创建一个数组来存储每个时间点的聚合流量
		$aggregatedFlows = [];

		// 查询所有端口的流量数据并按时间点聚合 1，2
		foreach ($ports as $port) {
			$flowData = SwitchPortFlow::where('switch_id', $port->switch_id)
				->where('switch_port_id', $port->port_index)
				->whereBetween('timeline_5min', [$startOfMonth, $endOfMonth])
				->select(
					'timeline_5min',
					DB::raw('GREATEST(in_rates, out_rates) as max_rate')
				)
				->get();
           
            // 调试输出上一段代码的sql
            // DB::listen(function ($flowData) {
            //     var_dump($flowData->sql);
            // });
          

			// 按时间点聚合多个端口的流量
			foreach ($flowData as $flow) {
				$timeKey = $flow->timeline_5min;
				if (!isset($aggregatedFlows[$timeKey])) {
					$aggregatedFlows[$timeKey] = 0;
				}
				$aggregatedFlows[$timeKey] += $flow->max_rate;
			}
		}
 

		// 将参考值转换为 bps (Gbps to bps)
		$referenceValueInBps = $referenceValue * 1000 * 1000 * 1000 / 8 ;
      
		// 计算超过参考值的点位数
		foreach ($aggregatedFlows as $totalRate) {
			if ($totalRate > $referenceValueInBps) {
				$usedPoints++;
			}
		}

		return $usedPoints;
	}

	public function tree()
    {
        $categories = [
            ['label' => '客户侧流量统计', 'value' => 1],
            ['label' => '供应商流量统计', 'value' => 2],
            ['label' => '运营商流量统计', 'value' => 3]
        ];

        // 获取机房数据,并按 idc_belong 分组
        $idcNodes = app()->make(IdcnodeService::class)
            ->query()
            ->get(['id', 'idc_name as name', 'idc_belong'])
            ->groupBy('idc_belong');

        // 构建树形结构
        return collect($categories)->map(function($category) use ($idcNodes) {
            // 获取当前分类对应的机房节点
            $categoryNodes = $idcNodes->get($category['value'], collect());
            
            return [
                'label' => $category['label'],
                'value' => $category['value'],
                'to' => '/node_management?type_id=' . $category['value'],
                'children' => $categoryNodes->map(function($idc) use ($category) {
                    return [
                        'label' => $idc->name,
                        'value' => $idc->id,
                        'to' => '/node_management?type_id=' . $category['value'] . '&idc_id=' . $idc->id
                    ];
                })->toArray()
            ];
        })->toArray();
    }

    /**
     * 获取节点详细信息，包含关联业务和签约公司
     */
    public function getDetail($id)
    {
        return $this->query()
            ->with([
                'operator:id,name',
                'switch:id,name,status',
                'customer_bus' => function($query) {
                    $query->with('sign_company', 'operator');
                }
            ])
            ->find($id);
    }
}